#include "Acceptor.h"
#include "EventLoop.h"
#include "InetAddress.h"
#include "Channel.h"

#include <sys/socket.h>
#include <netinet/in.h>
#include <unistd.h>
#include "Logger.h"
#include <arpa/inet.h>

namespace GiSo {

Acceptor::Acceptor(EventLoop* loop, const InetAddress& listenAddr)
    : m_Loop(loop)
    , m_AcceptSocket(socket(AF_INET, SOCK_STREAM | SOCK_NONBLOCK | SOCK_CLOEXEC, 0))
    , m_AcceptChannel(std::make_unique<Channel>(m_Loop, m_AcceptSocket))
    , m_NewConnectionCallback()
{
    if (m_AcceptSocket < 0) {
        GS_ERROR("Acceptor::Acceptor socket error");
    }

    int optval = 1;
    setsockopt(m_AcceptSocket, SOL_SOCKET, SO_REUSEADDR, &optval, sizeof(optval));

    struct sockaddr_in addr;
    addr.sin_family = AF_INET;
    addr.sin_addr.s_addr = inet_addr(listenAddr.GetIp().c_str()); // 假设 InetAddress 可以返回 ip string
    addr.sin_port = htons(listenAddr.GetPort());

    if (bind(m_AcceptSocket, (struct sockaddr*)&addr, sizeof(addr)) < 0) {
        GS_ERROR("Acceptor::Acceptor bind error");
    }

    m_AcceptChannel->SetReadCallback(std::bind(&Acceptor::HandleAccept, this));
}

Acceptor::~Acceptor()
{
    m_AcceptChannel->DisableAllEvents();
    m_AcceptChannel->Remove();
    m_AcceptChannel->Close();
}

void Acceptor::Listen()
{
    if (listen(m_AcceptSocket, 128) < 0) { // backlog 设为 128
        GS_ERROR("Acceptor::Listen listen error");
    }
    m_AcceptChannel->EnableReading();
}

void Acceptor::HandleAccept()
{
    while (true) { // 添加一个循环来处理多个连接
        struct sockaddr_in clientAddr;
        socklen_t clientLen = sizeof(clientAddr);
        int connfd = accept4(m_AcceptSocket, (struct sockaddr*)&clientAddr, &clientLen, SOCK_NONBLOCK | SOCK_CLOEXEC);

        if (connfd < 0) {
            if (errno == EAGAIN || errno == EWOULDBLOCK) {
                // 这表示没有更多连接可以立即接受了 (对于非阻塞 socket 是正常情况)
                GS_DEBUG("Acceptor::HandleAccept no more connections to accept immediately");
                break; // 退出循环，等待下一次 epoll 事件通知
            } else {
                GS_ERROR("Acceptor::HandleAccept accept4 error: {}", strerror(errno));
                // 这里可以根据实际情况决定是否继续循环或者直接返回
                // 为了避免无限循环错误，这里选择退出循环
                break;
            }
        }

        // Extract client's IP address and port (这部分保持不变)
        char clientIp[INET_ADDRSTRLEN];
        if (inet_ntop(AF_INET, &clientAddr.sin_addr, clientIp, sizeof(clientIp)) == nullptr) {
            GS_ERROR("Acceptor::HandleAccept inet_ntop error");
            close(connfd);
            continue; // 继续下一次循环，尝试接受更多连接
        }
        int clientPort = ntohs(clientAddr.sin_port);

        InetAddress clientInetAddr(clientIp, clientPort);

        GS_INFO("Accepted connection from {0}:{1}", clientIp, clientPort);

        if (m_NewConnectionCallback) {
            std::unique_ptr<Channel> channel = std::make_unique<Channel>(m_Loop, connfd);
            m_NewConnectionCallback(std::move(channel), clientInetAddr);
        } else {
            close(connfd); // No callback set, close connection
        }
    } // end whi
}

} // namespace GiSo